package com.niiwoo.civet.account.service.local;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.account.dao.entity.BankCard;
import com.niiwoo.civet.account.dao.entity.BankType;
import com.niiwoo.civet.account.dao.entity.WithdrawOrder;
import com.niiwoo.civet.account.dao.mapper.BankCardMapperExt;
import com.niiwoo.civet.account.dao.mapper.BankTypeMapperExt;
import com.niiwoo.civet.account.dto.common.sendmessage.*;
import com.niiwoo.civet.account.dto.request.RepaymentWithholdFailMsgMQDTO;
import com.niiwoo.civet.account.enums.BillFirstSubjectEnum;
import com.niiwoo.civet.account.enums.RepaymentTypeLetterEnum;
import com.niiwoo.civet.base.enums.BorrowProjectTypeEnum;
import com.niiwoo.civet.base.enums.DeadlineUnitEnum;
import com.niiwoo.civet.base.enums.RefundTypeEnum;
import com.niiwoo.civet.trade.dto.common.ProjectDTO;
import com.niiwoo.civet.trade.enums.ProjectFromSourceEnum;
import com.niiwoo.civet.trade.service.project.ProjectDubboService;
import com.niiwoo.civet.user.dto.request.AppButtonDTO;
import com.niiwoo.civet.user.dto.request.JPushExtDTO;
import com.niiwoo.civet.user.dto.request.UserLetterRequestDTO;
import com.niiwoo.civet.user.enums.JPushEnum;
import com.niiwoo.civet.user.enums.MessageTemplateKeyEnum;
import com.niiwoo.civet.user.enums.SMSTemplateKeyEnum;
import com.niiwoo.civet.user.enums.UserLetterTypeEnum;
import com.niiwoo.civet.user.service.SendSmsDubboService;
import com.niiwoo.civet.user.service.UserBasicInfoDubboService;
import com.niiwoo.civet.user.service.UserLetterDubboService;
import com.niiwoo.tripod.base.component.PrivacyMasks;
import com.niiwoo.tripod.base.plan.support.AmountHandleConstant;
import com.niiwoo.tripod.base.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.FastDateFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;

/**
 * @Description 推送消息通知
 * @Author Jaylin
 * @Date 2017-12-18
 */
@Service
@Slf4j
public class MessageSendLocalService {

    @Reference(version = "1.0.0")
    UserLetterDubboService userLetterDubboService;

    @Reference(version = "1.0.0")
    SendSmsDubboService sendSmsDubboService;


    @Reference(version = "1.0.0")
    private UserBasicInfoDubboService userBasicInfoDubboService;
    
    @Value("${h5-borrow-detail-url}")
	private String h5BorrowDetailUrl;

    @Autowired
    private BankCardMapperExt bankCardMapperExt;

    @Autowired
    private BankTypeMapperExt bankTypeMapperExt;
    @Autowired
    private PrivacyMasks privacyMasks;

    @Reference(version = "1.0.0")
    private ProjectDubboService projectDubboService;

    /**
     * 发送还款成功的站内信(考拉)
     * @param repaymentSuccessDTO
     */
    public void sendLetterForRepaymentFromKaola(RepaymentSuccessDTO repaymentSuccessDTO) {
        checkParamsForRepayment(repaymentSuccessDTO);
        log.info("还款成功,传入的参数:项目id={},项目标题={}",repaymentSuccessDTO.getProjectId(),repaymentSuccessDTO.getProjectTitle());

        Long projectId = repaymentSuccessDTO.getProjectId();
        String projectTitle = repaymentSuccessDTO.getProjectTitle();
        int currentPeriod = repaymentSuccessDTO.getCurrentPeriod();
        int totalPeriods = repaymentSuccessDTO.getTotalPeriods();
        BigDecimal successRepaymentAmount = repaymentSuccessDTO.getSuccessRepaymentAmount();
        //发站内信
        AppButtonDTO loanButton = new AppButtonDTO();
        loanButton.setLabel("借款详情");
        loanButton.setButtonType(AppButtonDTO.ButtonTypeEnum.MONMY_LOAN_DETAILEY_2);
        Map<String, Object> loanButtonParam = new HashMap<>();
        loanButtonParam.put("ProjectId", repaymentSuccessDTO.getProjectId());
        loanButtonParam.put("LoadServerUrl", h5BorrowDetailUrl+repaymentSuccessDTO.getProjectId());
        loanButton.setParams(loanButtonParam);

        List<AppButtonDTO> listForButton = new ArrayList<>();
        listForButton.add(loanButton);
        UserLetterRequestDTO letterRequestDTO = new UserLetterRequestDTO();
        letterRequestDTO.setToUserId(repaymentSuccessDTO.getUserId());
        letterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.LETTER_AND_JPUSH);
        letterRequestDTO.setLetterButtonList(listForButton);

        List<Object> letterTemplateParamList =  Arrays.asList(
                projectId,
                projectTitle,
                currentPeriod+"/"+totalPeriods,
                successRepaymentAmount
        );
        List<Object> jPushTemplateParamList =  Arrays.asList(
                projectTitle,
                currentPeriod+"/"+totalPeriods,
                successRepaymentAmount
        );
        MessageTemplateKeyEnum.LetterTemplateKeyEnum letterTemplateKeyEnum = null;
        MessageTemplateKeyEnum.JPushTemplateKeyEnum jPushTemplateKeyEnum = null;
        if (RepaymentTypeLetterEnum.REPAYMENT_SUCCESS.getType().equals(repaymentSuccessDTO.getRepaymentTypeLetterEnum().getType())) {
            letterTemplateKeyEnum = MessageTemplateKeyEnum.LetterTemplateKeyEnum.BORROW_REPAYMENT_SUCCESS;
            jPushTemplateKeyEnum = MessageTemplateKeyEnum.JPushTemplateKeyEnum.BORROW_REPAYMENT_SUCCESS;
        }else if (RepaymentTypeLetterEnum.REPAYMENT_SUCCESS_COMPLETE.getType().equals(repaymentSuccessDTO.getRepaymentTypeLetterEnum().getType())) {
            letterTemplateKeyEnum = MessageTemplateKeyEnum.LetterTemplateKeyEnum.BORROW_REPAYMENT_SUCCESS_COMPLETE;
            jPushTemplateKeyEnum = MessageTemplateKeyEnum.JPushTemplateKeyEnum.BORROW_REPAYMENT_SUCCESS_COMPLETE;
        }else if (RepaymentTypeLetterEnum.REPAYMENT_SUCCESS_ADVANCE.getType().equals(repaymentSuccessDTO.getRepaymentTypeLetterEnum().getType())) {
            letterTemplateKeyEnum = MessageTemplateKeyEnum.LetterTemplateKeyEnum.BORROW_REPAYMENT_ADVANCE;
            jPushTemplateKeyEnum = MessageTemplateKeyEnum.JPushTemplateKeyEnum.BORROW_REPAYMENT_ADVANCE;
        }
        letterRequestDTO.setLetterTemplateParamList(letterTemplateParamList);

        // 极光推送
        letterRequestDTO.setLetterTemplateEnum(letterTemplateKeyEnum);
        letterRequestDTO.setJpushTemplateKeyEnum(jPushTemplateKeyEnum);
        letterRequestDTO.setJpushTemplateParamList(jPushTemplateParamList);
        letterRequestDTO.setToUserId(repaymentSuccessDTO.getUserId());
        letterRequestDTO.setProjectId(repaymentSuccessDTO.getProjectId());
        letterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.LETTER_AND_JPUSH);
        JPushExtDTO jPushExtDTO = new JPushExtDTO();
        jPushExtDTO.setRedirectPageEnum(JPushEnum.RedirectPageEnum.NOTICE_LIST_PAGE);
        letterRequestDTO.setJPushExt(jPushExtDTO);
        userLetterDubboService.pushLetter(letterRequestDTO);
    }


    /**
     * 发送还款成功的站内信
     * @param repaymentSuccessDTO
     */
    public void sendLetterForRepayment(RepaymentSuccessDTO repaymentSuccessDTO) {
        checkParamsForRepayment(repaymentSuccessDTO);
        log.info("还款成功,传入的参数:项目id={},项目标题={}",repaymentSuccessDTO.getProjectId(),repaymentSuccessDTO.getProjectTitle());

        Long projectId = repaymentSuccessDTO.getProjectId();
        String projectTitle = repaymentSuccessDTO.getProjectTitle();
        int currentPeriod = repaymentSuccessDTO.getCurrentPeriod();
        int totalPeriods = repaymentSuccessDTO.getTotalPeriods();
        BigDecimal successRepaymentAmount = repaymentSuccessDTO.getSuccessRepaymentAmount();
        //发站内信
        AppButtonDTO messageButton = new AppButtonDTO();
        messageButton.setLabel("项目群");
        messageButton.setButtonType(AppButtonDTO.ButtonTypeEnum.PROJECT_GROUP);
        Map<String, Object> messageButtonParam = new HashMap<>();
        messageButtonParam.put("ProjectId", repaymentSuccessDTO.getProjectId());
        messageButton.setParams(messageButtonParam);

        AppButtonDTO loanButton = new AppButtonDTO();
        loanButton.setLabel("借款详情");
        loanButton.setButtonType(AppButtonDTO.ButtonTypeEnum.MONMY_LOAN_DETAILEY_2);
        Map<String, Object> loanButtonParam = new HashMap<>();
        loanButtonParam.put("ProjectId", repaymentSuccessDTO.getProjectId());
        loanButtonParam.put("LoadServerUrl", h5BorrowDetailUrl+repaymentSuccessDTO.getProjectId());
        loanButton.setParams(loanButtonParam);

        List<AppButtonDTO> listForButton = new ArrayList<>();
        listForButton.add(messageButton);
        listForButton.add(loanButton);
        UserLetterRequestDTO letterRequestDTO = new UserLetterRequestDTO();
        letterRequestDTO.setToUserId(repaymentSuccessDTO.getUserId());
        letterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.LETTER_AND_JPUSH);
        letterRequestDTO.setLetterButtonList(listForButton);

        List<Object> letterTemplateParamList =  Arrays.asList(
                projectId,
                projectTitle,
                currentPeriod+"/"+totalPeriods,
                successRepaymentAmount
        );
        List<Object> jPushTemplateParamList =  Arrays.asList(
                projectTitle,
                currentPeriod+"/"+totalPeriods,
                successRepaymentAmount
        );
        MessageTemplateKeyEnum.LetterTemplateKeyEnum letterTemplateKeyEnum = null;
        MessageTemplateKeyEnum.JPushTemplateKeyEnum jPushTemplateKeyEnum = null;
        if (RepaymentTypeLetterEnum.REPAYMENT_SUCCESS.getType().equals(repaymentSuccessDTO.getRepaymentTypeLetterEnum().getType())) {
            letterTemplateKeyEnum = MessageTemplateKeyEnum.LetterTemplateKeyEnum.BORROW_REPAYMENT_SUCCESS;
            jPushTemplateKeyEnum = MessageTemplateKeyEnum.JPushTemplateKeyEnum.BORROW_REPAYMENT_SUCCESS;
        }else if (RepaymentTypeLetterEnum.REPAYMENT_SUCCESS_COMPLETE.getType().equals(repaymentSuccessDTO.getRepaymentTypeLetterEnum().getType())) {
            letterTemplateKeyEnum = MessageTemplateKeyEnum.LetterTemplateKeyEnum.BORROW_REPAYMENT_SUCCESS_COMPLETE;
            jPushTemplateKeyEnum = MessageTemplateKeyEnum.JPushTemplateKeyEnum.BORROW_REPAYMENT_SUCCESS_COMPLETE;
        }else if (RepaymentTypeLetterEnum.REPAYMENT_SUCCESS_ADVANCE.getType().equals(repaymentSuccessDTO.getRepaymentTypeLetterEnum().getType())) {
            letterTemplateKeyEnum = MessageTemplateKeyEnum.LetterTemplateKeyEnum.BORROW_REPAYMENT_ADVANCE;
            jPushTemplateKeyEnum = MessageTemplateKeyEnum.JPushTemplateKeyEnum.BORROW_REPAYMENT_ADVANCE;
        }
        letterRequestDTO.setLetterTemplateParamList(letterTemplateParamList);

        // 极光推送
        letterRequestDTO.setLetterTemplateEnum(letterTemplateKeyEnum);
        letterRequestDTO.setJpushTemplateKeyEnum(jPushTemplateKeyEnum);
        letterRequestDTO.setJpushTemplateParamList(jPushTemplateParamList);
        letterRequestDTO.setToUserId(repaymentSuccessDTO.getUserId());
        letterRequestDTO.setProjectId(repaymentSuccessDTO.getProjectId());
        letterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.LETTER_AND_JPUSH);
        JPushExtDTO jPushExtDTO = new JPushExtDTO();
        jPushExtDTO.setRedirectPageEnum(JPushEnum.RedirectPageEnum.NOTICE_LIST_PAGE);
        letterRequestDTO.setJPushExt(jPushExtDTO);
        userLetterDubboService.pushLetter(letterRequestDTO);
    }

    /**
     * 还款逾期发送站内信
     * @param repaymentOverdueDTO
     */
    public void sendLetterForRepaymentOverdue(RepaymentOverdueDTO repaymentOverdueDTO) {
        checkParamsForRepaymentOverdue(repaymentOverdueDTO);
        log.info("还款逾期,传入的参数:项目id={},项目标题={}",repaymentOverdueDTO.getProjectId(),repaymentOverdueDTO.getProjectTitle());

        List<Object> listForLetter =  new ArrayList<>();
        listForLetter.add(String.valueOf(repaymentOverdueDTO.getProjectId()));
        listForLetter.add(repaymentOverdueDTO.getProjectTitle());
        listForLetter.add(String.valueOf(repaymentOverdueDTO.getCurrentPeriod()));
        listForLetter.add(String.valueOf(repaymentOverdueDTO.getTotalPeriods()));
        listForLetter.add(String.valueOf(repaymentOverdueDTO.getHavePayAmount()));
        listForLetter.add(String.valueOf(repaymentOverdueDTO.getNeedPayAmount()));
        listForLetter.add(String.valueOf(repaymentOverdueDTO.getOverdueDays()));

        AppButtonDTO appButtonDTO = new AppButtonDTO();
        appButtonDTO.setButtonType(AppButtonDTO.ButtonTypeEnum.SEE_BILL);
        Map<String, Object> map = new HashMap();
        map.put("billType", BillFirstSubjectEnum.USER_REPAYMENT);
        appButtonDTO.setParams(map);
        List<AppButtonDTO> listForButton = new ArrayList<>();
        listForButton.add(appButtonDTO);

        UserLetterRequestDTO letterRequestDTO = new UserLetterRequestDTO();
        letterRequestDTO.setToUserId(repaymentOverdueDTO.getUserId());
        letterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.ONLY_LETTER);
        letterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.BORROW_REPAYMENT_OVERDUE);
        letterRequestDTO.setLetterButtonList(listForButton);
        letterRequestDTO.setLetterTemplateParamList(listForLetter);
        userLetterDubboService.pushLetter(letterRequestDTO);
    }

    /**
     * 还款逾期发送短信
     * @param repaymentOverdueDTO
     */
    public void sendSmsForRepaymentOverdue(RepaymentOverdueDTO repaymentOverdueDTO) {
        checkParamsForRepaymentOverdue(repaymentOverdueDTO);
        log.info("还款逾期,传入的参数:项目id={},项目标题={}",repaymentOverdueDTO.getProjectId(),repaymentOverdueDTO.getProjectTitle());
        this.notifyToUser(
                repaymentOverdueDTO.getProjectId(),
                projectDTO -> {

                },
                projectDTO -> {
                    List<Object> listForLetter =  new ArrayList<>();
                    listForLetter.add(repaymentOverdueDTO.getProjectId());
                    listForLetter.add(repaymentOverdueDTO.getProjectTitle());
                    listForLetter.add(repaymentOverdueDTO.getCurrentPeriod());
                    listForLetter.add(repaymentOverdueDTO.getTotalPeriods());
                    listForLetter.add(repaymentOverdueDTO.getHavePayAmount());
                    listForLetter.add(repaymentOverdueDTO.getNeedPayAmount());
                    listForLetter.add(repaymentOverdueDTO.getOverdueDays());
                    sendSmsDubboService.sendSmsByUserId(repaymentOverdueDTO.getUserId(), SMSTemplateKeyEnum.TEMP_REPAYMENT_OVERUDUE.getKey(), listForLetter);
                }
        );

    }

	/**
	 * 借款成功,发送短信/站内信
	 * 
	 * @param lendSuccessNotifyDTO
	 */
	public void sendNotfyForLendSuccess(LendSuccessNotifyDTO lendSuccessNotifyDTO) {
		Assert.notNull(lendSuccessNotifyDTO, "lendSuccessNotifyDTO不能为空");
		Assert.notNull(lendSuccessNotifyDTO.getLendSuccessBorrowerNotifyDTO(),
				"lendSuccessNotifyDTO.getLendSuccessBorrowerNotifyDTO 不能为空");
		Assert.notEmpty(lendSuccessNotifyDTO.getLendSuccessInvestorNotifyDTOList(),
				"lendSuccessNotifyDTO.getLendSuccessInvestorNotifyDTOList 不能为空");

		lendSuccessBorrowerNotify(lendSuccessNotifyDTO.getLendSuccessBorrowerNotifyDTO());


        if(lendSuccessNotifyDTO.getIsPackagedProject() == null || !lendSuccessNotifyDTO.getIsPackagedProject()) {
            lendSuccessInvestorNotify(lendSuccessNotifyDTO.getLendSuccessBorrowerNotifyDTO().getProjectId(), lendSuccessNotifyDTO.getLendSuccessInvestorNotifyDTOList());
        }
	}

	/**
	 * 放款成功，借款人发送站内信、极光推送、短信
	 * 
	 * @param lendSuccessBorrowerNotifyDTO
	 */
	private void lendSuccessBorrowerNotify(LendSuccessBorrowerNotifyDTO lendSuccessBorrowerNotifyDTO) {
        Assert.notNull(lendSuccessBorrowerNotifyDTO.getUserId(), "用户id不能为空");
        Assert.notNull(lendSuccessBorrowerNotifyDTO.getProjectId(), "项目id不能为空");
        Assert.notNull(lendSuccessBorrowerNotifyDTO.getProjectTitle(), "标题不能为空");
	    notifyToUser(
                lendSuccessBorrowerNotifyDTO.getProjectId(),
                projectDTO -> {
                    List<Object> listForParams = new ArrayList<>();
                    listForParams.add(lendSuccessBorrowerNotifyDTO.getProjectTitle());
                    sendSmsDubboService.sendSmsByUserId(lendSuccessBorrowerNotifyDTO.getUserId(), SMSTemplateKeyEnum.CARD_NIU_TEMP_BORROW_SUCCESS.getKey(), listForParams);
                },
                projectDTO -> {
                    log.info("借款成功,传入的参数:项目id={},项目标题={}", lendSuccessBorrowerNotifyDTO.getProjectId(),
                            lendSuccessBorrowerNotifyDTO.getProjectTitle());

                    List<Object> listForLetter = new ArrayList<>();
                    listForLetter.add(String.valueOf(lendSuccessBorrowerNotifyDTO.getProjectId()));
                    listForLetter.add(lendSuccessBorrowerNotifyDTO.getProjectTitle());
                    listForLetter.add(lendSuccessBorrowerNotifyDTO.getBorrowAmount().toPlainString());
                    listForLetter.add(lendSuccessBorrowerNotifyDTO.getWithdrawFee().toPlainString());
                    listForLetter.add(lendSuccessBorrowerNotifyDTO.getRealAmount().toPlainString());

                    // 钱小二
                    AppButtonDTO appButtonDTO = new AppButtonDTO();
                    appButtonDTO.setButtonType(AppButtonDTO.ButtonTypeEnum.MONEY_2);
                    appButtonDTO.setLabel(AppButtonDTO.ButtonTypeEnum.MONEY_2.getDesc());

                    // 借款详情
                    AppButtonDTO loanButton = new AppButtonDTO();
                    loanButton.setLabel(AppButtonDTO.ButtonTypeEnum.MONMY_LOAN_DETAILEY_2.getDesc());
                    loanButton.setButtonType(AppButtonDTO.ButtonTypeEnum.MONMY_LOAN_DETAILEY_2);
                    Map<String, Object> loanButtonParam = new HashMap<>();
                    loanButtonParam.put("ProjectId", lendSuccessBorrowerNotifyDTO.getProjectId());
                    loanButtonParam.put("LoadServerUrl", lendSuccessBorrowerNotifyDTO.getH5BorrowDetailUrl()
                            + lendSuccessBorrowerNotifyDTO.getProjectId());
                    loanButton.setParams(loanButtonParam);

                    List<AppButtonDTO> listForButton = new ArrayList<>();
                    listForButton.add(appButtonDTO);
                    listForButton.add(loanButton);
                    UserLetterRequestDTO letterRequestDTO = new UserLetterRequestDTO();
                    letterRequestDTO.setToUserId(lendSuccessBorrowerNotifyDTO.getUserId());
                    letterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.LETTER_AND_JPUSH);
                    letterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.BORROW_SUCCESS_AUTO_WITHDRAW);
                    letterRequestDTO.setLetterButtonList(listForButton);
                    letterRequestDTO.setLetterTemplateParamList(listForLetter);

                    letterRequestDTO.setJpushTemplateKeyEnum(MessageTemplateKeyEnum.JPushTemplateKeyEnum.BORROW_SUCCESS_AUTO_WITHDRAW);
                    List<Object> jPushTemplateParamList = Arrays.asList(lendSuccessBorrowerNotifyDTO.getProjectTitle(),
                            lendSuccessBorrowerNotifyDTO.getBorrowAmount().toPlainString(),
                            lendSuccessBorrowerNotifyDTO.getWithdrawFee().toPlainString(),
                            lendSuccessBorrowerNotifyDTO.getRealAmount().toPlainString());
                    letterRequestDTO.setJpushTemplateParamList(jPushTemplateParamList);
                    JPushExtDTO jPushExtDTO = new JPushExtDTO();
                    jPushExtDTO.setRedirectPageEnum(JPushEnum.RedirectPageEnum.NOTICE_LIST_PAGE);
                    letterRequestDTO.setJPushExt(jPushExtDTO);

                    userLetterDubboService.pushLetter(letterRequestDTO);
                    // 发短信
                    List<Object> listForParams = new ArrayList<>();
                    listForParams.add(lendSuccessBorrowerNotifyDTO.getProjectTitle());
                    listForParams.add(lendSuccessBorrowerNotifyDTO.getBorrowAmount().toPlainString());
                    listForParams.add(lendSuccessBorrowerNotifyDTO.getWithdrawFee().toPlainString());
                    listForParams.add(lendSuccessBorrowerNotifyDTO.getRealAmount().toPlainString());

                    sendSmsDubboService.sendSmsByUserId(lendSuccessBorrowerNotifyDTO.getUserId(), SMSTemplateKeyEnum.TEMP_BORROW_SUCCESS_AUTO_WITHDRAW.getKey(), listForParams);


                    UserLetterRequestDTO letterRequestDTO2 = new UserLetterRequestDTO();
                    letterRequestDTO2.setToUserId(lendSuccessBorrowerNotifyDTO.getUserId());
                    letterRequestDTO2.setUserLetterTypeEnum(UserLetterTypeEnum.LETTER_AND_JPUSH);
                    letterRequestDTO2.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.LETTER_BORROW_SUCCESS_EVIDENCE_UPLOAD);
                    letterRequestDTO2.setJpushTemplateKeyEnum(MessageTemplateKeyEnum.JPushTemplateKeyEnum.BORROW_BORROW_SUCCESS_EVIDENCE_UPLOAD);

                    JPushExtDTO jPushExtDTO2 = new JPushExtDTO();
                    jPushExtDTO2.setRedirectPageEnum(JPushEnum.RedirectPageEnum.NOTICE_LIST_PAGE);
                    letterRequestDTO2.setJPushExt(jPushExtDTO2);

                    userLetterDubboService.pushLetter(letterRequestDTO2);
                    sendSmsDubboService.sendSmsByUserId(lendSuccessBorrowerNotifyDTO.getUserId(), SMSTemplateKeyEnum.TEMP_BORROW_SUCCESS_EVIDENCE_UPLOAD.getKey(), null);
                },
                projectDTO -> {
                    List<Object> listForParams = new ArrayList<>();
                    listForParams.add(lendSuccessBorrowerNotifyDTO.getProjectTitle());
                    sendSmsDubboService.sendSmsByUserId(lendSuccessBorrowerNotifyDTO.getUserId(), SMSTemplateKeyEnum.TO8TO_BORROW_SUCCESS.getKey(), listForParams);
                },
                projectDTO -> {
                    log.info("借款成功,传入的参数:项目id={},项目标题={}", lendSuccessBorrowerNotifyDTO.getProjectId(),
                            lendSuccessBorrowerNotifyDTO.getProjectTitle());

                    List<Object> listForLetter = new ArrayList<>();
                    listForLetter.add(String.valueOf(lendSuccessBorrowerNotifyDTO.getProjectId()));
                    listForLetter.add(lendSuccessBorrowerNotifyDTO.getProjectTitle());
                    // 发站内信
                    AppButtonDTO messageButton = new AppButtonDTO();
                    messageButton.setLabel("项目群");
                    messageButton.setButtonType(AppButtonDTO.ButtonTypeEnum.PROJECT_GROUP);
                    Map<String, Object> messageButtonParam = new HashMap<>();
                    messageButtonParam.put("ProjectId", lendSuccessBorrowerNotifyDTO.getProjectId());
                    messageButton.setParams(messageButtonParam);

                    AppButtonDTO loanButton = new AppButtonDTO();
                    loanButton.setLabel("借款详情");
                    loanButton.setButtonType(AppButtonDTO.ButtonTypeEnum.MONMY_LOAN_DETAILEY_2);
                    Map<String, Object> loanButtonParam = new HashMap<>();
                    loanButtonParam.put("ProjectId", lendSuccessBorrowerNotifyDTO.getProjectId());
                    loanButtonParam.put("LoadServerUrl", lendSuccessBorrowerNotifyDTO.getH5BorrowDetailUrl()
                            + lendSuccessBorrowerNotifyDTO.getProjectId());
                    loanButton.setParams(loanButtonParam);

                    List<AppButtonDTO> listForButton = new ArrayList<>();
                    listForButton.add(messageButton);
                    listForButton.add(loanButton);
                    UserLetterRequestDTO letterRequestDTO = new UserLetterRequestDTO();
                    letterRequestDTO.setToUserId(lendSuccessBorrowerNotifyDTO.getUserId());
                    letterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.LETTER_AND_JPUSH);
                    letterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.BORRO_SUCCESS);
                    letterRequestDTO.setLetterButtonList(listForButton);
                    letterRequestDTO.setLetterTemplateParamList(listForLetter);

                    letterRequestDTO.setJpushTemplateKeyEnum(MessageTemplateKeyEnum.JPushTemplateKeyEnum.BORRO_SUCCESS);
                    List<Object> jPushTemplateParamList = Arrays.asList(lendSuccessBorrowerNotifyDTO.getProjectTitle());
                    letterRequestDTO.setJpushTemplateParamList(jPushTemplateParamList);
                    JPushExtDTO jPushExtDTO = new JPushExtDTO();
                    jPushExtDTO.setRedirectPageEnum(JPushEnum.RedirectPageEnum.NOTICE_LIST_PAGE);
                    letterRequestDTO.setJPushExt(jPushExtDTO);

                    userLetterDubboService.pushLetter(letterRequestDTO);
                    // 发短信
                    List<Object> listForParams = new ArrayList<>();
                    listForParams.add(lendSuccessBorrowerNotifyDTO.getProjectTitle());

                    sendSmsDubboService.sendSmsByUserId(lendSuccessBorrowerNotifyDTO.getUserId(), SMSTemplateKeyEnum.TEMP_BORROW_SUCCESS.getKey(), listForParams);
                }
        );



	}

	/**
	 * 投资放款成功发送通知给投资人
	 * 
	 * @param lendSuccessInvestorNotifyDTOList
	 */
	private void lendSuccessInvestorNotify(Long projectId, List<LendSuccessInvestorNotifyDTO> lendSuccessInvestorNotifyDTOList) {
		Assert.notEmpty(lendSuccessInvestorNotifyDTOList, "lendSuccessInvestorNotifyDTOList不能为空");

        ProjectDTO project = projectDubboService.selectProjectById(projectId);

        boolean isOrgSpeedloanNew = project.getType().equals(BorrowProjectTypeEnum.ORG_SPEEDLOAN_NEW.getValue());
        boolean isTu8tu = project.getType().equals(BorrowProjectTypeEnum.DECORATION_LOAN.getValue());

		for (LendSuccessInvestorNotifyDTO lendSuccessInvestorNotifyDTO : lendSuccessInvestorNotifyDTOList) {
			Assert.notNull(lendSuccessInvestorNotifyDTO, "iendSuccessInvestorNotifyDTO 不能为空");
			log.info("投资放款成功发送通知给投资人,传入的参数:项目id={},项目标题={},投资订单ID={}", lendSuccessInvestorNotifyDTO.getProjectId(),
					lendSuccessInvestorNotifyDTO.getProjectTitle(), lendSuccessInvestorNotifyDTO.getInvestOrderId());
			List<Object> listForLetter = new ArrayList<>();
			listForLetter.add(String.valueOf(lendSuccessInvestorNotifyDTO.getProjectId()));
			listForLetter.add(lendSuccessInvestorNotifyDTO.getProjectTitle());

			// 投资详情按钮
			AppButtonDTO investDetailButton = new AppButtonDTO();
			investDetailButton.setButtonType(AppButtonDTO.ButtonTypeEnum.MY_INVESTMENT_DETAIL);
			investDetailButton.setLabel("投资详情");
			Map<String, Object> buttonMap = new HashMap<>();
			buttonMap.put("ProjectId", lendSuccessInvestorNotifyDTO.getProjectId());
			buttonMap.put("LoadServerUrl", lendSuccessInvestorNotifyDTO.getH5InvestDetailUrl() + "?investOrderId=" + lendSuccessInvestorNotifyDTO.getInvestOrderId());
			buttonMap.put("InvestOrderId", lendSuccessInvestorNotifyDTO.getInvestOrderId());
			investDetailButton.setParams(buttonMap);

			// 项目群按钮
			AppButtonDTO messageButton = new AppButtonDTO();
			messageButton.setLabel("项目群");
			messageButton.setButtonType(AppButtonDTO.ButtonTypeEnum.PROJECT_GROUP);
			Map<String, Object> messageButtonParam = new HashMap<>();
			messageButtonParam.put("ProjectId", lendSuccessInvestorNotifyDTO.getProjectId());
			messageButton.setParams(messageButtonParam);

			List<AppButtonDTO> listForButton = new ArrayList<>();
			listForButton.add(investDetailButton);
            if (!isOrgSpeedloanNew && !isTu8tu) {
                listForButton.add(messageButton);
            }

			// 发站内信
			UserLetterRequestDTO letterRequestDTO = new UserLetterRequestDTO();
			letterRequestDTO.setToUserId(lendSuccessInvestorNotifyDTO.getUserId());
			letterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.ONLY_LETTER);
			if(isOrgSpeedloanNew || isTu8tu) {
                letterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.INVEST_ORG_PROJECT_LEND_SUCCESS);
            } else {
                letterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.INVEST_LEND_SUCCESS);
            }
			letterRequestDTO.setLetterButtonList(listForButton);
			letterRequestDTO.setLetterTemplateParamList(listForLetter);

			userLetterDubboService.pushLetter(letterRequestDTO);
		}
	}

    /**
     * 收款成功发送站内信
     * @param investReceiveDTO
     */
    public void sendLetterForInvestReceive(InvestReceiveDTO investReceiveDTO) {
        checkParamsForReceive(investReceiveDTO);
        log.info("收款成功,传入的参数:用户id={},收款日期={}",investReceiveDTO.getUserId(),investReceiveDTO.getReceiveDate());

        List<Object> listForLetter =  new ArrayList<>();
        listForLetter.add(investReceiveDTO.getReceiveDate());
        listForLetter.add(String.valueOf(investReceiveDTO.getReceiveBidCount()));
        if(investReceiveDTO.getOverDebtCount() > 0)
            listForLetter.add(String.valueOf(investReceiveDTO.getOverDebtCount()));
        listForLetter.add(String.valueOf(investReceiveDTO.getReceiveAmount()));
        listForLetter.add(String.valueOf(investReceiveDTO.getReceiveCorpus()));
        listForLetter.add(String.valueOf(investReceiveDTO.getReceiveInterest()));
        listForLetter.add(String.valueOf(investReceiveDTO.getReceiveOverdueFine()));

        //跳转按钮
        AppButtonDTO appButtonDTO = new AppButtonDTO();
        appButtonDTO.setLabel("查看账单");
        appButtonDTO.setButtonType(AppButtonDTO.ButtonTypeEnum.SEE_BILL);
        Map<String, Object> map = new HashMap<>();
        map.put("billType", BillFirstSubjectEnum.USER_INVEST_REPAYMENT);
        appButtonDTO.setParams(map);
        List<AppButtonDTO> listForButton = new ArrayList<>();
        listForButton.add(appButtonDTO);

        //站内信请求参数
        UserLetterRequestDTO letterRequestDTO = new UserLetterRequestDTO();
        letterRequestDTO.setToUserId(investReceiveDTO.getUserId());
        letterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.LETTER_AND_JPUSH);
        if(investReceiveDTO.getOverDebtCount() > 0)
            letterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.OVER_RECEIVE_ADVANCE);
        else
            letterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.INVEST_RECEIVE);
        letterRequestDTO.setLetterButtonList(listForButton);
        letterRequestDTO.setLetterTemplateParamList(listForLetter);

        //极光推送请求参数
        if(investReceiveDTO.getOverDebtCount() > 0)
            letterRequestDTO.setJpushTemplateKeyEnum(MessageTemplateKeyEnum.JPushTemplateKeyEnum.OVER_RECEIVE_ADVANCE);
        else
            letterRequestDTO.setJpushTemplateKeyEnum(MessageTemplateKeyEnum.JPushTemplateKeyEnum.INVEST_RECEIVE);
        letterRequestDTO.setJpushTemplateParamList(listForLetter);
        JPushExtDTO jPushExtDTO = new JPushExtDTO();
        jPushExtDTO.setRedirectPageEnum(JPushEnum.RedirectPageEnum.NOTICE_LIST_PAGE);
        letterRequestDTO.setJPushExt(jPushExtDTO);

        userLetterDubboService.pushLetter(letterRequestDTO);
    }

    /**
     * 收款成功发送短信
     * @param investReceiveDTO
     */
    public void sendSmsForInvestReceive(InvestReceiveDTO investReceiveDTO) {
        checkParamsForReceive(investReceiveDTO);
        log.info("收款成功,传入的参数:用户id={},收款日期={}",investReceiveDTO.getUserId(),investReceiveDTO.getReceiveDate());

        List<Object> listForSms =  new ArrayList<>();
        listForSms.add(investReceiveDTO.getReceiveDate());
        listForSms.add(investReceiveDTO.getReceiveBidCount());
        listForSms.add(investReceiveDTO.getReceiveCorpus());
        listForSms.add(investReceiveDTO.getReceiveInterest());
        listForSms.add(investReceiveDTO.getReceiveOverdueFine());
        sendSmsDubboService.sendSmsByUserId(investReceiveDTO.getUserId(), SMSTemplateKeyEnum.TEMP_INVEST_RECEIVE_SUCCESS.getKey(), listForSms);
    }

    /**
     * 投资回款通知:发送站内信通知(正常+提前)
     * @param advanceDTO
     */
    public void sendLetterForInvestReceiveAdvance(Byte batchRefundType, InvestReceiveAdvanceDTO advanceDTO) {
        checkParamsForReceiveAdvance(advanceDTO);
        if(advanceDTO.getIsPackagedProject() != null && advanceDTO.getIsPackagedProject()){
            sendLetterForInvestPackageReceiveAdvance(advanceDTO);
        } else {
            log.info("投资回款,传入的参数:项目id={},项目标题={}", advanceDTO.getProjectId(), advanceDTO.getProjectTitle());

            List<Object> letterTemplateParamList = Arrays.asList(
                    advanceDTO.getProjectId(),
                    advanceDTO.getProjectTitle(),
                    advanceDTO.getReceiveDate(),
                    advanceDTO.getReceiveAmount(),
                    advanceDTO.getReceiveTotalAmount(),
                    advanceDTO.getReceiveCorpus(),
                    advanceDTO.getReceiveInterest(),
                    advanceDTO.getReceiveOverdueFine()
            );
            List<Object> jpushAndSmsTemplateParamList = Arrays.asList(
                    advanceDTO.getProjectTitle(),
                    advanceDTO.getReceiveDate(),
                    advanceDTO.getReceiveAmount(),
                    advanceDTO.getReceiveTotalAmount(),
                    advanceDTO.getReceiveCorpus(),
                    advanceDTO.getReceiveInterest(),
                    advanceDTO.getReceiveOverdueFine()
            );

            //跳转按钮
            AppButtonDTO appButtonDTO = new AppButtonDTO();
            appButtonDTO.setLabel("查看账单");
            appButtonDTO.setButtonType(AppButtonDTO.ButtonTypeEnum.SEE_BILL);

            Map<String, Object> map = new HashMap<>();
            map.put("billType", BillFirstSubjectEnum.USER_INVEST_REPAYMENT);
            appButtonDTO.setParams(map);

            List<AppButtonDTO> listForButton = new ArrayList<>();
            listForButton.add(appButtonDTO);

            UserLetterRequestDTO letterRequestDTO = new UserLetterRequestDTO();
            //站内信请求参数
            letterRequestDTO.setToUserId(advanceDTO.getUserId());
            letterRequestDTO.setProjectId(advanceDTO.getProjectId());
            letterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.LETTER_AND_JPUSH);
            if (RefundTypeEnum.OVERDEPT.getRefundType().equals(batchRefundType)) {
                letterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.INVEST_RECEIVE_ADVANCE);
            } else {
                letterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.NORMAL_RECEIVE_ADVANCE);
            }
            letterRequestDTO.setLetterButtonList(listForButton);
            letterRequestDTO.setLetterTemplateParamList(letterTemplateParamList);

            //极光推送请求参数
            if (RefundTypeEnum.OVERDEPT.getRefundType().equals(batchRefundType)) {
                letterRequestDTO.setJpushTemplateKeyEnum(MessageTemplateKeyEnum.JPushTemplateKeyEnum.INVEST_RECEIVE_ADVANCE);
            } else {
                letterRequestDTO.setJpushTemplateKeyEnum(MessageTemplateKeyEnum.JPushTemplateKeyEnum.NORMAL_RECEIVE_ADVANCE);
            }
            JPushExtDTO jPushExtDTO = new JPushExtDTO();
            jPushExtDTO.setRedirectPageEnum(JPushEnum.RedirectPageEnum.NOTICE_LIST_PAGE);
            letterRequestDTO.setJPushExt(jPushExtDTO);
            letterRequestDTO.setJpushTemplateParamList(jpushAndSmsTemplateParamList);

            userLetterDubboService.pushLetter(letterRequestDTO);
        }
    }

    private void sendLetterForInvestPackageReceiveAdvance(InvestReceiveAdvanceDTO advanceDTO){
        log.info("sendLetterForInvestPackageReceiveAdvance advanceDTO:{}", JSON.toJSON(advanceDTO));

        //跳转按钮
        AppButtonDTO appButtonDTO = new AppButtonDTO();
        appButtonDTO.setLabel("查看账单");
        appButtonDTO.setButtonType(AppButtonDTO.ButtonTypeEnum.SEE_BILL);

        Map<String, Object> map = new HashMap<>();
        map.put("billType", BillFirstSubjectEnum.USER_INVEST_REPAYMENT);
        appButtonDTO.setParams(map);

        List<AppButtonDTO> listForButton = new ArrayList<>();
        listForButton.add(appButtonDTO);

        UserLetterRequestDTO letterRequestDTO = new UserLetterRequestDTO();
        //站内信请求参数
        letterRequestDTO.setToUserId(advanceDTO.getUserId());
        letterRequestDTO.setProjectId(advanceDTO.getProjectId());
        letterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.LETTER_AND_JPUSH);


        if (Byte.valueOf("1").equals(advanceDTO.getPackageInvestOrderReceivedType())) {
            letterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.PROJECT_PACKAGE_OVERDEPT_RECEIVE);
            letterRequestDTO.setJpushTemplateKeyEnum(MessageTemplateKeyEnum.JPushTemplateKeyEnum.PROJECT_PACKAGE_OVERDEPT_RECEIVE);
        } else if (Byte.valueOf("2").equals(advanceDTO.getPackageInvestOrderReceivedType())){
            letterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.PROJECT_PACKAGE_RECEIVE);
            letterRequestDTO.setJpushTemplateKeyEnum(MessageTemplateKeyEnum.JPushTemplateKeyEnum.PROJECT_PACKAGE_RECEIVE);
        } else {
            letterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.PROJECT_PACKAGE_FINISH_RECEIVE);
            letterRequestDTO.setJpushTemplateKeyEnum(MessageTemplateKeyEnum.JPushTemplateKeyEnum.PROJECT_PACKAGE_FINISH_RECEIVE);
        }

        DecimalFormat df = new DecimalFormat("###,###.##");
        String submitDate = DateUtils.format(advanceDTO.getPackageInvestOrderSubmitTime(), "yyyy年MM月dd日");
        String serviceName = advanceDTO.getPackageTitle() + "【" + advanceDTO.getDeadline() + (DeadlineUnitEnum.BY_MONTH.getDeadlineUnit().equals(advanceDTO.getDeadlineUnit()) ? "月" : "日")  +"】";

        Integer receivedProjectNum = advanceDTO.getCurrentPeriodPackageReceivedProjectNum();

        String currentPeriodPackageInvestOrderReceiveTotalAmountDesc = df.format(advanceDTO.getCurrentPeriodPackageInvestOrderReceiveTotalAmount() == null ? BigDecimal.ZERO : advanceDTO.getCurrentPeriodPackageInvestOrderReceiveTotalAmount());
        String receivedCapitalDesc = "：" + df.format(advanceDTO.getReceiveCorpus() == null ? BigDecimal.ZERO : advanceDTO.getReceiveCorpus());
        String receivedInterestDesc = "：" + df.format(advanceDTO.getReceiveInterest() == null ? BigDecimal.ZERO : advanceDTO.getReceiveInterest());
        String receiveTotalAmountDesc = "：" + df.format(advanceDTO.getReceiveTotalAmount() == null ? BigDecimal.ZERO : advanceDTO.getReceiveTotalAmount());

        String penaltyFeeDesc = "";
        if(advanceDTO.getReceiveOverdueFine() != null && advanceDTO.getReceiveOverdueFine().compareTo(BigDecimal.ZERO) > 0){
            penaltyFeeDesc = "\n罚息：" + df.format(advanceDTO.getReceiveOverdueFine());
        }

        List<Object> letterTemplateParamList;
        List<Object> jpushAndSmsTemplateParamList;

        if (Byte.valueOf("1").equals(advanceDTO.getPackageInvestOrderReceivedType())) {
            letterTemplateParamList = Arrays.asList(
                    submitDate,
                    serviceName,
                    receiveTotalAmountDesc,
                    receivedCapitalDesc,
                    receivedInterestDesc,
                    penaltyFeeDesc
            );
            jpushAndSmsTemplateParamList = Arrays.asList(
                    submitDate,
                    serviceName,
                    receiveTotalAmountDesc,
                    receivedCapitalDesc,
                    receivedInterestDesc,
                    penaltyFeeDesc
            );
        } else if(Byte.valueOf("2").equals(advanceDTO.getPackageInvestOrderReceivedType())){
            letterTemplateParamList = Arrays.asList(
                    submitDate,
                    serviceName,
                    receivedProjectNum,
                    currentPeriodPackageInvestOrderReceiveTotalAmountDesc,
                    receivedCapitalDesc,
                    receivedInterestDesc,
                    penaltyFeeDesc
            );
            jpushAndSmsTemplateParamList = Arrays.asList(
                    submitDate,
                    serviceName,
                    receivedProjectNum,
                    currentPeriodPackageInvestOrderReceiveTotalAmountDesc,
                    receivedCapitalDesc,
                    receivedInterestDesc,
                    penaltyFeeDesc
            );
        } else {
            receivedProjectNum = advanceDTO.getPackageInvestOrderReceivedProjectNum();
            String packageInvestOrderReceiveTotalAmountDesc = "：" + df.format(advanceDTO.getPackageInvestOrderReceiveTotalAmount() == null ? BigDecimal.ZERO : advanceDTO.getPackageInvestOrderReceiveTotalAmount());
            //String packageInvestOrderReceiveCapitalDesc = "：" + df.format(advanceDTO.getPackageInvestOrderReceiveCapital() == null ? BigDecimal.ZERO : advanceDTO.getPackageInvestOrderReceiveCapital());
            //String packageInvestOrderReceiveInterestDesc = "：" + df.format(advanceDTO.getPackageInvestOrderReceiveInterest() == null ? BigDecimal.ZERO : advanceDTO.getPackageInvestOrderReceiveInterest());
            //String packageInvestOrderReceivePenaltyFeeDesc = "";
            //if(advanceDTO.getPackageInvestOrderReceivePenaltyFee() != null && advanceDTO.getPackageInvestOrderReceivePenaltyFee().compareTo(BigDecimal.ZERO) > 0){
            //    packageInvestOrderReceivePenaltyFeeDesc = "\n罚息：" + df.format(advanceDTO.getPackageInvestOrderReceivePenaltyFee());
            //}

            letterTemplateParamList = Arrays.asList(
                    submitDate,
                    serviceName,
                    receivedProjectNum,
                    packageInvestOrderReceiveTotalAmountDesc,
                    receivedCapitalDesc,
                    receivedInterestDesc,
                    penaltyFeeDesc
            );
            jpushAndSmsTemplateParamList = Arrays.asList(
                    submitDate,
                    serviceName,
                    receivedProjectNum,
                    packageInvestOrderReceiveTotalAmountDesc,
                    receivedCapitalDesc,
                    receivedInterestDesc,
                    penaltyFeeDesc
            );
        }

        letterRequestDTO.setLetterButtonList(listForButton);
        letterRequestDTO.setLetterTemplateParamList(letterTemplateParamList);

        JPushExtDTO jPushExtDTO = new JPushExtDTO();
        jPushExtDTO.setRedirectPageEnum(JPushEnum.RedirectPageEnum.NOTICE_LIST_PAGE);
        letterRequestDTO.setJPushExt(jPushExtDTO);
        letterRequestDTO.setJpushTemplateParamList(jpushAndSmsTemplateParamList);

        userLetterDubboService.pushLetter(letterRequestDTO);
    }

    /**
     * 发送短信/消息-换绑卡审核通过.
     *
     * @param sendMessageDTO
     */
    public void sendMsgForChangeBankCardAduitPassed(SendMessageDTO sendMessageDTO) {
        Assert.notNull(sendMessageDTO.getUserId(), "发送的对象用户id不能为空");
        //发送短信
        sendSmsDubboService.sendSmsByUserId(sendMessageDTO.getUserId(), SMSTemplateKeyEnum.TEMP_CHANGE_BANK_CARD_AUDIT_PASSED.getKey(), null);

        //发送站内信
        UserLetterRequestDTO userLetterRequestDTO = new UserLetterRequestDTO();
        userLetterRequestDTO.setToUserId(sendMessageDTO.getUserId());
        userLetterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.ONLY_LETTER);

        //设置站内信按钮
        AppButtonDTO appButtonDTO = new AppButtonDTO();
        appButtonDTO.setButtonType(AppButtonDTO.ButtonTypeEnum.BANK_ACCOUNT_INFO);
        appButtonDTO.setLabel(AppButtonDTO.ButtonTypeEnum.BANK_ACCOUNT_INFO.getDesc());
        List<AppButtonDTO> listForButton = new ArrayList<>();
        listForButton.add(appButtonDTO);

        //站内信模板Key
        userLetterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.TEMP_CHANGE_BANK_CARD_AUDIT_PASSED);
        userLetterRequestDTO.setLetterButtonList(listForButton);
        userLetterDubboService.pushLetter(userLetterRequestDTO);
    }

    /**
     * 发送短信/消息-换绑卡审核不通过.
     *
     * @param sendMessageDTO
     */
    public void sendMsgForChangeBankCardAduitNotPassed(SendMessageDTO sendMessageDTO, List<Object> params) {
        Assert.notNull(sendMessageDTO.getUserId(), "发送的对象用户id不能为空");
        //发送短信
        sendSmsDubboService.sendSmsByUserId(sendMessageDTO.getUserId(), SMSTemplateKeyEnum.TEMP_CHANGE_BANK_CARD_AUDIT_NOT_PASSED.getKey(), params);
        //发送站内信
        UserLetterRequestDTO userLetterRequestDTO = new UserLetterRequestDTO();
        userLetterRequestDTO.setToUserId(sendMessageDTO.getUserId());
        userLetterRequestDTO.setLetterTemplateParamList(params);
        userLetterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.ONLY_LETTER);

        //设置站内信按钮
        AppButtonDTO appButtonDTO = new AppButtonDTO();
        appButtonDTO.setButtonType(AppButtonDTO.ButtonTypeEnum.BANK_ACCOUNT_INFO);
        appButtonDTO.setLabel(AppButtonDTO.ButtonTypeEnum.BANK_ACCOUNT_INFO.getDesc());
        List<AppButtonDTO> listForButton = new ArrayList<>();
        listForButton.add(appButtonDTO);

        //站内信模板Key
        userLetterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.TEMP_CHANGE_BANK_CARD_AUDIT_NOT_PASSED);
        userLetterRequestDTO.setLetterButtonList(listForButton);
        userLetterDubboService.pushLetter(userLetterRequestDTO);
    }

    /**
     *
     * 发送短信/消息-提现失败.
     *
     * @param sendMsgForWithdrawDTO
     */
    public void sendMsgForWithdrawFail(SendMsgForWithdrawDTO sendMsgForWithdrawDTO) {
        Assert.notNull(sendMsgForWithdrawDTO.getUserId(), "发送的对象用户id不能为空");
        Assert.notNull(sendMsgForWithdrawDTO.getDateTime(), "发送的对象用户提现时间（MM月dd日HH:mm）不能为空");
        Assert.notNull(sendMsgForWithdrawDTO.getAmount(), "发送的对象用户提现金额不能为空");
        String dateForSend = DateUtils.formatDate(sendMsgForWithdrawDTO.getDateTime(), DateUtils.DATETIME_FOMAT_CHINESE);
        String amount = sendMsgForWithdrawDTO.getAmount().setScale(AmountHandleConstant.CALCULATE_PRECISION_TWO, BigDecimal.ROUND_HALF_EVEN).toString();
        //发送短信
        Object[] strParamsForSMS = new Object[]{dateForSend, amount};
        List<Object> listForParams = Arrays.asList(strParamsForSMS);
        sendSmsDubboService.sendSmsByUserId(sendMsgForWithdrawDTO.getUserId(), SMSTemplateKeyEnum.TEMP_WITHDRAW_FAIL.getKey(), listForParams);

        //发送站内信
        UserLetterRequestDTO userLetterRequestDTO = new UserLetterRequestDTO();
        userLetterRequestDTO.setToUserId(sendMsgForWithdrawDTO.getUserId());
        userLetterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.ONLY_LETTER);
        //站内信模板Key
        userLetterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.TEMP_WITHDRAW_FAIL);
        userLetterRequestDTO.setLetterTemplateParamList(listForParams);
        userLetterDubboService.pushLetter(userLetterRequestDTO);
    }

    /**
     * 发送还款提醒的站内信
     * @param repaymentRemindDTO
     */
    public void sendLetterForRepaymentRemind(RepaymentRemindDTO repaymentRemindDTO) {
        log.info("还款成功,传入的参数:项目id={},项目标题={}",repaymentRemindDTO.getProjectId(),repaymentRemindDTO.getProjectTitle());

        List<Object> listForLetter =  new ArrayList<>();
        listForLetter.add(String.valueOf(repaymentRemindDTO.getProjectId()));
        listForLetter.add(String.valueOf(repaymentRemindDTO.getProjectTitle()));
        listForLetter.add(String.valueOf(repaymentRemindDTO.getCurrentPeriod()));
        listForLetter.add(String.valueOf(repaymentRemindDTO.getTotalPeriods()));
        listForLetter.add(String.valueOf(repaymentRemindDTO.getAmount()));

        AppButtonDTO loanButton = new AppButtonDTO();
        loanButton.setLabel("借款详情");
        loanButton.setButtonType(AppButtonDTO.ButtonTypeEnum.MONMY_LOAN_DETAILEY_2);
        Map<String, Object> loanButtonParam = new HashMap<>();
        loanButtonParam.put("ProjectId", repaymentRemindDTO.getProjectId());
        loanButtonParam.put("LoadServerUrl", h5BorrowDetailUrl+repaymentRemindDTO.getProjectId());
        loanButton.setParams(loanButtonParam);

        List<AppButtonDTO> listForButton = new ArrayList<>();
        listForButton.add(loanButton);
        UserLetterRequestDTO letterRequestDTO = new UserLetterRequestDTO();
        letterRequestDTO.setToUserId(repaymentRemindDTO.getUserId());
        letterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.LETTER_AND_JPUSH);
        letterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.BORROW_REPAYMENT_REMIND);
        letterRequestDTO.setLetterButtonList(listForButton);
        letterRequestDTO.setLetterTemplateParamList(listForLetter);
        userLetterDubboService.pushLetter(letterRequestDTO);
    }

    private void checkParamsForRepayment(RepaymentSuccessDTO repaymentSuccessDTO) {
        Assert.notNull(repaymentSuccessDTO.getProjectId(),"项目id不能为空");
        Assert.notNull(repaymentSuccessDTO.getProjectTitle(),"标题不能为空");
        Assert.notNull(repaymentSuccessDTO.getCurrentPeriod(),"期数不能为空");
        Assert.notNull(repaymentSuccessDTO.getSuccessRepaymentAmount(),"成功还款金额不能为空");
        Assert.notNull(repaymentSuccessDTO.getTotalPeriods(),"总期数不能为空");
        Assert.notNull(repaymentSuccessDTO.getRepaymentTypeLetterEnum(),"枚举类型不能传空");
    }

    private void checkParamsForRepaymentOverdue(RepaymentOverdueDTO repaymentOverdueDTO) {
        Assert.notNull(repaymentOverdueDTO.getUserId(),"用户id不能为空");
        Assert.notNull(repaymentOverdueDTO.getProjectId(),"项目id不能为空");
        Assert.notNull(repaymentOverdueDTO.getProjectTitle(),"标题不能为空");
        Assert.notNull(repaymentOverdueDTO.getCurrentPeriod(),"期数不能为空");
        Assert.notNull(repaymentOverdueDTO.getTotalPeriods(),"总期数不能为空");
        Assert.notNull(repaymentOverdueDTO.getHavePayAmount(),"已还金额不能为空");
        Assert.notNull(repaymentOverdueDTO.getNeedPayAmount(),"还需还款金额不能为空");
        Assert.notNull(repaymentOverdueDTO.getOverdueDays(),"逾期天数不能为空");
    }

    private void checkParamsForReceive(InvestReceiveDTO investReceiveDTO) {
        Assert.notNull(investReceiveDTO.getUserId(),"用户id不能为空");
        Assert.notNull(investReceiveDTO.getReceiveDate(),"收款日期不能为空");
        Assert.notNull(investReceiveDTO.getReceiveBidCount(),"收款标的个数不能为空");
        Assert.notNull(investReceiveDTO.getReceiveCorpus(),"收款本金不能为空");
        Assert.notNull(investReceiveDTO.getReceiveInterest(),"收款利息不能为空");
        Assert.notNull(investReceiveDTO.getReceiveOverdueFine(),"收款罚息不能为空");
    }

    private void checkParamsForReceiveAdvance(InvestReceiveAdvanceDTO investReceiveAdvanceDTO) {
        Assert.notNull(investReceiveAdvanceDTO.getUserId(),"用户id不能为空");
        Assert.notNull(investReceiveAdvanceDTO.getProjectId(),"项目id不能为空");
        Assert.notNull(investReceiveAdvanceDTO.getProjectTitle(),"项目标题不能为空");
        Assert.notNull(investReceiveAdvanceDTO.getReceiveDate(),"收款日期不能为空");
        Assert.notNull(investReceiveAdvanceDTO.getReceiveTotalAmount(),"收款总额不能为空");
        Assert.notNull(investReceiveAdvanceDTO.getReceiveCorpus(),"收款本金不能为空");
        Assert.notNull(investReceiveAdvanceDTO.getReceiveInterest(),"收款利息不能为空");
        Assert.notNull(investReceiveAdvanceDTO.getReceiveOverdueFine(),"收款罚息不能为空");
    }

    public void accountWithholdFailMsgSend(RepaymentWithholdFailMsgMQDTO repaymentWithholdFailMsgMQDTO){

        this.notifyToUser(
                repaymentWithholdFailMsgMQDTO.getProjectId(),
                projectDTO -> {
                    String userId = repaymentWithholdFailMsgMQDTO.getUserId();
                    String projectTitle = repaymentWithholdFailMsgMQDTO.getProjectTitle();
                    String periodString = repaymentWithholdFailMsgMQDTO.getCurrentPeriod()+"/"+ repaymentWithholdFailMsgMQDTO.getTotalPeriod();
                    String refundDateString = FastDateFormat.getInstance("MM月dd日").format(repaymentWithholdFailMsgMQDTO.getRefundDate());
                    BigDecimal amount = repaymentWithholdFailMsgMQDTO.getAmount();
                    List<Object> jpushAndSmsTemplateParamList = Arrays.asList(
                            projectTitle,
                            periodString,
                            refundDateString,
                            amount
                    );
                    //发送短信
                    this.repaymentWithholdFailSmsMessageSend(userId, SMSTemplateKeyEnum.CARD_NIU_BORROW_ACCOUNT_DEBIT_FAIL,jpushAndSmsTemplateParamList);
                },
                projectDTO -> {
                    String userId = repaymentWithholdFailMsgMQDTO.getUserId();
                    Long projectId = repaymentWithholdFailMsgMQDTO.getProjectId();
                    String projectTitle = repaymentWithholdFailMsgMQDTO.getProjectTitle();
                    String periodString = repaymentWithholdFailMsgMQDTO.getCurrentPeriod()+"/"+ repaymentWithholdFailMsgMQDTO.getTotalPeriod();
                    String refundDateString = FastDateFormat.getInstance("MM月dd日").format(repaymentWithholdFailMsgMQDTO.getRefundDate());
                    BigDecimal amount = repaymentWithholdFailMsgMQDTO.getAmount();

                    List<Object> letterTemplateParamList = Arrays.asList(
                            projectId,
                            projectTitle,
                            periodString,
                            refundDateString,
                            amount
                    );
                    List<Object> jpushAndSmsTemplateParamList = Arrays.asList(
                            projectTitle,
                            periodString,
                            refundDateString,
                            amount
                    );
                    //发送站内信和极光推送
                    this.repaymentWithholdFailLetterMessageSend(
                            userId,projectId,
                            MessageTemplateKeyEnum.LetterTemplateKeyEnum.BORROW_ACCOUNT_DEBIT_FAIL,letterTemplateParamList,
                            MessageTemplateKeyEnum.JPushTemplateKeyEnum.BORROW_ACCOUNT_DEBIT_FAIL,jpushAndSmsTemplateParamList);

                    //发送短信
                    this.repaymentWithholdFailSmsMessageSend(userId, SMSTemplateKeyEnum.BORROW_ACCOUNT_DEBIT_FAIL,jpushAndSmsTemplateParamList);
                }
        );

    }

    private String getBankCardLastFour(Optional<BankCard> bankCardOpt){
        return bankCardOpt.map(BankCard::getBankAccountNo)
                .map(bankAccountNo->{
                    bankAccountNo = privacyMasks.decryptPrivacy(bankAccountNo);
                    return bankAccountNo.substring(bankAccountNo.length() - 4);
                }).orElse(null);
    }

    private String getBankName(Optional<BankCard> bankCardOpt){
        return bankCardOpt.map(BankCard::getBankCode)
                .map(bankCode->{
                    BankType bankType = bankTypeMapperExt.selectBankTypeByCode(bankCode);
                    return bankType==null?null:bankType.getBankName();
                }).orElse(null);
    }

    public void cardWithholdFailMsgSend(RepaymentWithholdFailMsgMQDTO repaymentWithholdFailMsgMQDTO){
        this.notifyToUser(
                repaymentWithholdFailMsgMQDTO.getProjectId(),
                projectDTO -> {
                    String userId = repaymentWithholdFailMsgMQDTO.getUserId();
                    String projectTitle = repaymentWithholdFailMsgMQDTO.getProjectTitle();
                    String periodString = repaymentWithholdFailMsgMQDTO.getCurrentPeriod()+"/"+ repaymentWithholdFailMsgMQDTO.getTotalPeriod();
                    String refundDateString = FastDateFormat.getInstance("MM月dd日").format(repaymentWithholdFailMsgMQDTO.getRefundDate());
                    BigDecimal amount = repaymentWithholdFailMsgMQDTO.getAmount();
                    Optional<BankCard> bankCardOpt = Optional.ofNullable(bankCardMapperExt.selectSimpleUserBankCard(userId));
                    String bankCardLastFour = this.getBankCardLastFour(bankCardOpt);
                    String bankName = this.getBankName(bankCardOpt);
                    List<Object> jpushAndSmsTemplateParamList = Arrays.asList(
                            projectTitle,
                            periodString,
                            amount,
                            refundDateString,
                            bankCardLastFour,
                            bankName
                    );
                    this.repaymentWithholdFailSmsMessageSend(userId, SMSTemplateKeyEnum.CARD_NIU_BORROW_CARD_WITHHOLD_FAIL, jpushAndSmsTemplateParamList);
                },
                projectDTO -> {
                    String userId = repaymentWithholdFailMsgMQDTO.getUserId();
                    Long projectId = repaymentWithholdFailMsgMQDTO.getProjectId();
                    String projectTitle = repaymentWithholdFailMsgMQDTO.getProjectTitle();
                    String periodString = repaymentWithholdFailMsgMQDTO.getCurrentPeriod()+"/"+ repaymentWithholdFailMsgMQDTO.getTotalPeriod();
                    String refundDateString = FastDateFormat.getInstance("MM月dd日").format(repaymentWithholdFailMsgMQDTO.getRefundDate());
                    BigDecimal amount = repaymentWithholdFailMsgMQDTO.getAmount();

                    Optional<BankCard> bankCardOpt = Optional.ofNullable(bankCardMapperExt.selectSimpleUserBankCard(userId));
                    String bankCardLastFour = this.getBankCardLastFour(bankCardOpt);
                    String bankName = this.getBankName(bankCardOpt);

                    List<Object> letterTemplateParamList = Arrays.asList(
                            projectId,
                            projectTitle,
                            periodString,
                            amount,
                            refundDateString,
                            bankCardLastFour,
                            bankName
                    );
                    List<Object> jpushAndSmsTemplateParamList = Arrays.asList(
                            projectTitle,
                            periodString,
                            amount,
                            refundDateString,
                            bankCardLastFour,
                            bankName
                    );
                    //发送站内信和极光推送
                    this.repaymentWithholdFailLetterMessageSend(
                            userId,projectId,
                            MessageTemplateKeyEnum.LetterTemplateKeyEnum.BORROW_CARD_WITHHOLD_FAIL,letterTemplateParamList,
                            MessageTemplateKeyEnum.JPushTemplateKeyEnum.BORROW_CARD_WITHHOLD_FAIL,jpushAndSmsTemplateParamList);

                    //发送短信
                    this.repaymentWithholdFailSmsMessageSend(userId, SMSTemplateKeyEnum.BORROW_CARD_WITHHOLD_FAIL,jpushAndSmsTemplateParamList);
                }
        );

    }

    private void repaymentWithholdFailLetterMessageSend(
            String userId,
            Long projectId,
            MessageTemplateKeyEnum.LetterTemplateKeyEnum letterTemplateKeyEnum, List<Object> letterTemplateParamList,
            MessageTemplateKeyEnum.JPushTemplateKeyEnum jPushTemplateKeyEnum, List<Object> jpushTemplateParamList){
        UserLetterRequestDTO letterRequest = new UserLetterRequestDTO();
        letterRequest.setUserLetterTypeEnum(UserLetterTypeEnum.LETTER_AND_JPUSH);

        AppButtonDTO rechargeButton = new AppButtonDTO();
        rechargeButton.setLabel("充值");
        rechargeButton.setButtonType(AppButtonDTO.ButtonTypeEnum.RECHARGE);

        AppButtonDTO loanButton = new AppButtonDTO();
        loanButton.setLabel("借款详情");
        loanButton.setButtonType(AppButtonDTO.ButtonTypeEnum.MONMY_LOAN_DETAILEY_2);
        Map<String, Object> loanButtonParam = new HashMap<>();
        loanButtonParam.put("ProjectId", projectId);
        loanButtonParam.put("LoadServerUrl", h5BorrowDetailUrl+projectId);
        loanButton.setParams(loanButtonParam);

        letterRequest.setLetterButtonList(Arrays.asList(rechargeButton,loanButton));
        letterRequest.setToUserId(userId);
        letterRequest.setProjectId(projectId);
        letterRequest.setLetterTemplateEnum(letterTemplateKeyEnum);
        letterRequest.setLetterTemplateParamList(letterTemplateParamList);

        JPushExtDTO jPushExtDTO = new JPushExtDTO();
        jPushExtDTO.setRedirectPageEnum(JPushEnum.RedirectPageEnum.NOTICE_LIST_PAGE);
        letterRequest.setJPushExt(jPushExtDTO);
        letterRequest.setJpushTemplateKeyEnum(jPushTemplateKeyEnum);
        letterRequest.setJpushTemplateParamList(jpushTemplateParamList);

        log.info("还款提醒###扣款失败###消息通知###请求, project={}, data={}", projectId, JSON.toJSONString(letterRequest));
        CompletableFuture.runAsync(() -> userLetterDubboService.pushLetter(letterRequest))
                .whenComplete((success, throwable) -> {
                    if (throwable != null) {
                        log.error(String.format("还款提醒###扣款失败###消息通知###异常, project=%s, errorMessage=%s", projectId, throwable.getMessage()), throwable);
                    }
                });
    }

    private void repaymentWithholdFailSmsMessageSend(String userId,SMSTemplateKeyEnum smsTemplateKeyEnum,List<Object> smsTemplateParamList){
        CompletableFuture.runAsync(() ->
            sendSmsDubboService.sendSmsByUserId(userId, smsTemplateKeyEnum.getKey(), smsTemplateParamList)
        ).whenComplete((success, throwable) -> {
            if (throwable != null) {
                log.error(String.format("还款提醒###扣款失败###短信###异常, userId=%s, errorMessage=%s", userId, throwable.getMessage()), throwable);
            }
        });
    }

    private void notifyToUser(Long projectId, Consumer<ProjectDTO> cardNiu, Consumer<ProjectDTO> other) {
        ProjectDTO project = projectDubboService.selectProjectById(projectId);
        boolean isCardLoan = project.getType().equals(com.niiwoo.civet.trade.enums.ProjectTypeEnum.CARD_NIU_LOAN.getValue());
        boolean isFormCardNiu = project.getFromSource().equals(ProjectFromSourceEnum.CARD_NIU.getType());
        if (isCardLoan && isFormCardNiu) {
            if (cardNiu != null) {
                cardNiu.accept(project);
            }
        } else {
            other.accept(project);
        }
    }

    private void notifyToUser(Long projectId, Consumer<ProjectDTO> cardNiu,  Consumer<ProjectDTO> lendAutoWithdraw, Consumer<ProjectDTO> tu8tu, Consumer<ProjectDTO> other) {
        ProjectDTO project = projectDubboService.selectProjectById(projectId);
        boolean isCardLoan = project.getType().equals(com.niiwoo.civet.trade.enums.ProjectTypeEnum.CARD_NIU_LOAN.getValue());
        boolean isFormCardNiu = project.getFromSource().equals(ProjectFromSourceEnum.CARD_NIU.getType());
        boolean isLendAutoWithdraw = project.getType().equals(BorrowProjectTypeEnum.SMALL_LOAN.getValue())
                || project.getType().equals(BorrowProjectTypeEnum.SOCIAL_SECURITY_LOAN.getValue())
                || project.getType().equals(BorrowProjectTypeEnum.CREDIT_CARD_LOAN.getValue())
                || project.getType().equals(BorrowProjectTypeEnum.CONSUME_LOAN.getValue());

        boolean isOrgSpeedloanNew = project.getType().equals(BorrowProjectTypeEnum.ORG_SPEEDLOAN_NEW.getValue());
        boolean isTu8tu = project.getType().equals(BorrowProjectTypeEnum.DECORATION_LOAN.getValue());
        if (isCardLoan && isFormCardNiu) {
            if (cardNiu != null) {
                cardNiu.accept(project);
            }
        } else if(isLendAutoWithdraw){
            if (lendAutoWithdraw != null) {
                lendAutoWithdraw.accept(project);
            }
        } else if (isOrgSpeedloanNew) {
            // 机构极速借 不进行通知
        } else if(isTu8tu){
            if (tu8tu != null) {
                tu8tu.accept(project);
            }
        } else {
            other.accept(project);
        }
    }

    public void sendMsgForWithdrawFailToCardNiu(ProjectDTO project) {
        sendSmsDubboService.sendSmsByUserId(project.getBorrowUserId(), SMSTemplateKeyEnum.CARD_NIU_INVEST_FINISHED_AND_WITHDRAW_FAIL.getKey(), Arrays.asList(project.getTitle()));
    }

    public void sendMsgForWithdrawFailToTo8tu(String borrowUserId, WithdrawOrder withdrawOrder) {
        SimpleDateFormat sdf = new SimpleDateFormat("MM月dd日");
        List<Object> params = new ArrayList<>();
        params.add(sdf.format(withdrawOrder.getCreateTime()));
        params.add(withdrawOrder.getAmount().toPlainString());
        sendSmsDubboService.sendSmsByUserId(borrowUserId, SMSTemplateKeyEnum.TO8TO_BORROW_SUCCESS_AUTO_WITHDRAW_FAIL.getKey(), params);
    }

    /**
     * 借款成功自动提现失败通知
     *
     * @param project
     */
    public void lendSuccessAutoWithdrawFailBorrowerNotify(ProjectDTO project) {
        List<Object> listForLetter = new ArrayList<>();
        listForLetter.add(String.valueOf(project.getProjectId()));
        listForLetter.add(project.getTitle());
        listForLetter.add(project.getContractAmount().toPlainString());
        // 发站内信
        AppButtonDTO appButtonDTO = new AppButtonDTO();
        appButtonDTO.setButtonType(AppButtonDTO.ButtonTypeEnum.MONEY_2);
        appButtonDTO.setLabel(AppButtonDTO.ButtonTypeEnum.MONEY_2.getDesc());

        AppButtonDTO loanButton = new AppButtonDTO();
        loanButton.setLabel("借款详情");
        loanButton.setButtonType(AppButtonDTO.ButtonTypeEnum.MONMY_LOAN_DETAILEY_2);
        Map<String, Object> loanButtonParam = new HashMap<>();
        loanButtonParam.put("ProjectId", project.getProjectId());
        loanButtonParam.put("LoadServerUrl", h5BorrowDetailUrl
                + project.getProjectId());
        loanButton.setParams(loanButtonParam);

        List<AppButtonDTO> listForButton = new ArrayList<>();
        listForButton.add(appButtonDTO);
        listForButton.add(loanButton);
        UserLetterRequestDTO letterRequestDTO = new UserLetterRequestDTO();
        letterRequestDTO.setToUserId(project.getBorrowUserId());
        letterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.LETTER_AND_JPUSH);
        letterRequestDTO.setLetterTemplateEnum(MessageTemplateKeyEnum.LetterTemplateKeyEnum.BORROW_SUCCESS_AUTO_WITHDRAW_FAIL);
        letterRequestDTO.setLetterButtonList(listForButton);
        letterRequestDTO.setLetterTemplateParamList(listForLetter);

        letterRequestDTO.setJpushTemplateKeyEnum(MessageTemplateKeyEnum.JPushTemplateKeyEnum.BORROW_SUCCESS_AUTO_WITHDRAW_FAIL);
        List<Object> jPushTemplateParamList = Arrays.asList(project.getTitle());
        letterRequestDTO.setJpushTemplateParamList(jPushTemplateParamList);
        JPushExtDTO jPushExtDTO = new JPushExtDTO();
        jPushExtDTO.setRedirectPageEnum(JPushEnum.RedirectPageEnum.NOTICE_LIST_PAGE);
        letterRequestDTO.setJPushExt(jPushExtDTO);

        userLetterDubboService.pushLetter(letterRequestDTO);
        // 发短信
        List<Object> listForParams = new ArrayList<>();
        listForParams.add(project.getTitle());
        listForParams.add(project.getContractAmount().toPlainString());

        sendSmsDubboService.sendSmsByUserId(project.getBorrowUserId(), SMSTemplateKeyEnum.TEMP_BORROW_SUCCESS_AUTO_WITHDRAW.getKey(), listForParams);
    }
}
